home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
050
/
tptool.lbr
/
SHELL.PQS
/
shell.pas
Wrap
Pascal/Delphi Source File
|
1985-06-03
|
7KB
|
231 lines
{$A-}
PROGRAM TOOLS;
{$I TOOLU.PAS}
PROCEDURE INITCMD;
{ Initialize command line; modified for double quotes }
{ Pipes added -- Willett Kempton, 3 January 1985 }
{ Multiple processes (sequential) added -- WK, 5 January 1985 }
CONST
PIPE = BAR;
SEQPRCS = SEMICOL;
VAR
FD,FDJUNK:FILEDESC;
FNAME:XSTRING;
FT:FILTYP;
IDX:1..MAXSTR;
JSKIP:INTEGER;
PendingProcess, { local variable only }
JUNK:BOOLEAN;
i,DEBUG2: INTEGER;
BEGIN
CMDFIL[STDIN]:=STDIO;
{ make STDOUT and STDERR normal buffered files; this eliminates
one layer of if checks and procedure calls }
NAMESTR(FNAME,'CON:');
for FD := STDOUT to STDERR do begin
CMDFIL[FD] := CLOSED;
FDJUNK := MUSTOPEN(FNAME,IOWRITE);
end;
{ CMDFIL[STDOUT]:=STDIO;
CMDFIL[STDERR]:=STDIO;
}
FOR FD:=SUCC(STDERR) TO MAXOPEN DO
CMDFIL[FD]:=CLOSED;
KBDN:=0;
if EntryFromHost then
begin
writeln('Software tools, version ',Version,
', type "help" for command list');
PendingProcess := FALSE;
SetEntryFromHost(FALSE);
end
else PendingProcess := ActiveProcessQ;
FromPipe := PendingProcess and (PipeCount > 0);
if PendingProcess
then
begin
SCOPY(ProcessQueue,1,CMDLIN,1);
if Debug or ListProcess then
PUTSTR(CMDLIN,STDERR);
if FromPipe then
begin
XCLOSE(STDIN);
GenPipeName(PipeCount,FNAME);
FD := MUSTOPEN(FNAME,IOREAD);
end;
end
else
begin
PipeCount := 0;
write(ShellPrompt);
ReadingShellCmd := true; { flag for GETKBD }
if (not getline(cmdlin,STDIN,MAXSTR)) then begin
writeln(' eof to shell'); ExitToHost; end;
ReadingShellCmd := false;
end;
CMDARGS:=0;
JSKIP:=0; { counts quotes already skipped }
IDX:=1;
WHILE (not (CMDLIN[IDX] in [ENDSTR,NEWLINE,PIPE,SEQPRCS])) DO
BEGIN
WHILE((CMDLIN[IDX]=BLANK)AND(JSKIP MOD 2 <>1))DO
IDX:=IDX+1;
IF NOT(CMDLIN[IDX] IN [NEWLINE,PIPE,SEQPRCS]) THEN
BEGIN { next argument }
CMDARGS:=CMDARGS+1;
CMDIDX[CMDARGS]:=IDX-JSKIP;
WHILE((CMDLIN[IDX]<>NEWLINE) AND
(NOT(CMDLIN[IDX] IN [BLANK,PIPE,SEQPRCS])OR(ODD(JSKIP)))) DO
BEGIN
IF (CMDLIN[IDX]=DQUOTE)
THEN JSKIP:=JSKIP+1
ELSE CMDLIN[IDX-JSKIP]:=CMDLIN[IDX];
IDX := IDX+1;
END;
if (CMDLIN[IDX] IN [PIPE,SEQPRCS]) then
for i:= MAXSTR downto (IDX-JSKIP+1) do { don't overwrite }
CMDLIN[i] := CMDLIN[i-1];
CMDLIN[IDX-JSKIP]:=ENDSTR;
IDX:=IDX+1;
{ redirection }
IF (CMDLIN[CMDIDX[CMDARGS]]=LESS) THEN
BEGIN
XCLOSE(STDIN);
CMDIDX[CMDARGS]:=CMDIDX[CMDARGS]+1;
JUNK:=GETARG(CMDARGS,FNAME,MAXSTR);
FD:=MUSTOPEN(FNAME,IOREAD);
CMDARGS:=CMDARGS-1;
END
ELSE
IF (CMDLIN[CMDIDX[CMDARGS]]=GREATER) THEN
BEGIN
XCLOSE(STDOUT);
CMDIDX[CMDARGS]:=CMDIDX[CMDARGS]+1;
JUNK:=GETARG(CMDARGS,FNAME,MAXSTR);
FD:=MUSTCREATE(FNAME,IOWRITE);
CMDARGS:=CMDARGS-1;
END
ELSE
IF Debug then
BEGIN
WRITE(' arg ',CMDARGS:1,' ');
DEBUG2 := CMDIDX[CMDARGS];
WHILE CMDLIN[DEBUG2]<>ENDSTR DO
BEGIN
WRITE(CHR(CMDLIN[DEBUG2])); DEBUG2:=DEBUG2+1;
END;
WRITELN;
END
END
END;
ToPipe := CMDLIN[IDX] = PIPE;
ActiveProcessQ := ToPipe or (CMDLIN[IDX]=SEQPRCS);
if ActiveProcessQ then
begin
SCOPY(CMDLIN,(IDX+1),ProcessQueue,1);{ preserve remainder of command }
if ToPipe then
begin
XCLOSE(STDOUT); PipeCount := PipeCount+1;
GenPipeName(PipeCount,FNAME);
FD := MUSTCREATE(FNAME,IOWRITE);
end;
end;
END { INITCMD };
procedure Shell;
{ Chain to proper file }
VAR CMDPTR:FILE;
str:STRING80;
COMMAND:XSTRING;
DONE:BOOLEAN;
I, Chapter, Position:INTEGER;
CONST
(* This is horribly non-standard (only Turbo), but saves memory *)
AllCmds: array[0..8] of string [54] =
(* must have blank before AND after each command *)
(' quit help ',
' charcount copy linecount wordcount detab list shell ',
' entab overstrike compress expand echo translit ',
' compare include concat print makecopy archive ',
' sort unique kwic unrotate ', { ' rotate ' not supported }
' find change ',
' edit ',
' format ',
' define macro ');
procedure GiveHelp;
var ch: integer;
begin
writeln; writeln('Commands:');
for ch:= 1 to 8 do
begin write(AllCmds[ch]); if ch in[1..3,6] then writeln end;
writeln(AllCmds[0]); writeln;
writeln('Symbols:');
write(' ''|'' pipe, '';'' next process,');
writeln(' redirection: ''>'' to file, ''<'' from file.');
write(' ''^Z'' (control-Z) terminate console input,');
writeln(' " " quote arguments.');
writeln;
end { GiveHelp };
function LowCase(c:char):char;
begin
if c in ['A'..'Z']
then LowCase := char(ord(c)+32)
else LowCase := c;
end;
PROCEDURE SETCHAIN(chapnum:char);
var len : integer; tempstr:string80;
BEGIN
ASSIGN(CMDPTR,CONCAT(SystemDrive,'CHAPTER',chapnum,'.CHN'));
(* put non-abbreviated form in global variable *)
len := length(AllCmds[Chapter]);
tempstr := copy(AllCmds[Chapter],(Position+1),(len-Position));
GlobalArg1 :=
copy( tempstr, 1, (pos(' ',tempstr)-1) ); (* strip commands after *)
DONE:=TRUE
END;
BEGIN { Shell }
DONE:=FALSE;
repeat
INITCMD;
IF GETARG(1,COMMAND,MAXSTR) THEN BEGIN
str:=' ';
FOR I:=1 TO XLENGTH(COMMAND) DO
str := CONCAT(str,LowCase(chr(COMMAND[I])));
if not Abbreviate then str := concat(str,' ');
Chapter := -1;
repeat
Chapter := Chapter + 1;
Position := Pos(str,AllCmds[Chapter]); { Turbo, nonstandard }
until (Chapter=9) or (Position>0);
if Chapter=0 then {pseudo-chapter "0"}
begin if Position=1 then ExitToHost else GiveHelp end
else if Position>0
then SETCHAIN(chr(Chapter+ord('0'))) { good command, real chapter }
else { bad command }
BEGIN WRITELN(str,'?');DONE:=FALSE END;
END { IF GETARG };
until DONE;
CHAIN(CMDPTR) { <-- if I/O Error 01, check configuration in TOOLU.PAS }
END { Shell };
BEGIN
Shell;
END.